home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
The World of Computer Software.iso
/
srcuc.zip
/
SYNTAX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-05-20
|
25KB
|
927 lines
/* -*-C-*-
$Header: /scheme/microcode/RCS/syntax.c,v 1.21 1991/05/20 20:31:51 cph Exp $
Copyright (c) 1987-91 Massachusetts Institute of Technology
This material was developed by the Scheme project at the Massachusetts
Institute of Technology, Department of Electrical Engineering and
Computer Science. Permission to copy this software, to redistribute
it, and to use it for any purpose is granted, subject to the following
restrictions and understandings.
1. Any copy made of this software must include this copyright notice
in full.
2. Users of this software agree to make their best efforts (a) to
return to the MIT Scheme project any improvements or extensions that
they make, so that these may be included in future releases; and (b)
to inform MIT of noteworthy uses of this software.
3. All materials developed as a consequence of the use of this
software shall duly acknowledge such use, in accordance with the usual
standards of acknowledging credit in academic research.
4. MIT has made no warrantee or representation that the operation of
this software will be error-free, and MIT is under no obligation to
provide any services, by way of maintenance, update, or otherwise.
5. In conjunction with products arising from the use of this material,
there shall be no use of the name of the Massachusetts Institute of
Technology nor of any adaptation thereof in any advertising,
promotional, or sales literature without prior written consent from
MIT in each case. */
/* Primitives to support Edwin syntax tables, word and list parsing. */
/* NOTE: This program was created by translation from the syntax table
code of GNU Emacs; it was translated from the original C to 68000
assembly language (in 1986), and then translated back from 68000
assembly language to C (in 1987). Users should be aware that the GNU
GENERAL PUBLIC LICENSE may apply to this code. A copy of that license
should have been included along with this file. */
#include "scheme.h"
#include "prims.h"
#include "edwin.h"
#include "syntax.h"
/* Syntax Codes */
/* Convert a letter which signifies a syntax code
into the code it signifies. */
#define ILLEGAL ((char) syntaxcode_max)
char syntax_spec_code[0200] =
{
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
((char) syntaxcode_whitespace), ILLEGAL, ((char) syntaxcode_string),
ILLEGAL, ((char) syntaxcode_math), ILLEGAL, ILLEGAL,
((char) syntaxcode_quote),
((char) syntaxcode_open), ((char) syntaxcode_close), ILLEGAL, ILLEGAL,
ILLEGAL, ((char) syntaxcode_whitespace), ((char) syntaxcode_punct),
((char) syntaxcode_charquote),
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ((char) syntaxcode_comment),
ILLEGAL, ((char) syntaxcode_endcomment), ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
((char) syntaxcode_word),
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ((char) syntaxcode_escape), ILLEGAL,
ILLEGAL, ((char) syntaxcode_symbol),
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
((char) syntaxcode_word),
ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL
};
/* Indexed by syntax code, give the letter that describes it. */
unsigned char syntax_code_spec[13] =
{
' ', '.', 'w', '_', '(', ')', '\'', '\"', '$', '\\', '/', '<', '>'
};
#define MERGE_PREFIX_BIT(result, bit) \
{ \
if ((result & bit) != 0) \
error_bad_range_arg (1); \
result |= bit; \
}
DEFINE_PRIMITIVE ("STRING->SYNTAX-ENTRY", Prim_string_to_syntax_entry, 1, 1, 0)
{
long length, c, result;
unsigned char * scan;
PRIMITIVE_HEADER (1);
CHECK_ARG (1, STRING_P);
length = (STRING_LENGTH (ARG_REF (1)));
scan = (STRING_LOC ((ARG_REF (1)), 0));
if ((length--) > 0)
{
c = (*scan++);
if (c >= 0200) error_bad_range_arg (1);
result = (syntax_spec_code [c]);
if (result == ILLEGAL) error_bad_range_arg (1);
}
else
result = ((long) syntaxcode_whitespace);
if ((length--) > 0)
{
c = (*scan++);
if (c != ' ') result |= (c << 8);
}
while ((length--) > 0)
switch (*scan++)
{
case '1': MERGE_PREFIX_BIT (result, (1 << 16)); break;
case '2': MERGE_PREFIX_BIT (result, (1 << 17)); break;
case '3': MERGE_PREFIX_BIT (result, (1 << 18)); break;
case '4': MERGE_PREFIX_BIT (result, (1 << 19)); break;
case 'p': MERGE_PREFIX_BIT (result, (1 << 20)); break;
case ' ': break;
default: error_bad_range_arg (1);
}
PRIMITIVE_RETURN (LONG_TO_UNSIGNED_FIXNUM (result));
}
DEFINE_PRIMITIVE ("CHAR->SYNTAX-CODE", Prim_char_to_syntax_code, 2, 2, 0)
{
PRIMITIVE_HEADER (2);
CHECK_ARG (1, SYNTAX_TABLE_P);
PRIMITIVE_RETURN
(ASCII_TO_CHAR
(syntax_code_spec
[((int)
(SYNTAX_ENTRY_CODE
(SYNTAX_TABLE_REF ((ARG_REF (1)), (arg_ascii_char (2))))))]));
}
/* Parser Initialization */
#define NORMAL_INITIALIZATION_COMMON(arity) \
fast SCHEME_OBJECT syntax_table; \
fast SCHEME_OBJECT group; \
fast unsigned char * start; \
unsigned char * first_char, * end; \
long sentry; \
long gap_length; \
PRIMITIVE_HEADER (arity); \
CHECK_ARG (1, SYNTAX_TABLE_P); \
syntax_table = (ARG_REF (1)); \
CHECK_ARG (2, GROUP_P); \
group = (ARG_REF (2)); \
first_char = (STRING_LOC ((GROUP_TEXT (group)), 0)); \
start = (first_char + (arg_nonnegative_integer (3))); \
end = (first_char + (arg_nonnegative_integer (4))); \
gap_start = (first_char + (GROUP_GAP_START (group))); \
gap_length = (GROUP_GAP_LENGTH (group)); \
gap_end = (first_char + (GROUP_GAP_END (group)))
#define NORMAL_INITIALIZATION_FORWARD(arity) \
unsigned char * gap_start; \
fast unsigned char * gap_end; \
NORMAL_INITIALIZATION_COMMON (arity); \
if (start >= gap_start) \
start += gap_length; \
if (end >= gap_start) \
end += gap_length
#define NORMAL_INITIALIZATION_BACKWARD(arity) \
fast unsigned char * gap_start; \
unsigned char * gap_end; \
Boolean quoted; \
NORMAL_INITIALIZATION_COMMON (arity); \
if (start > gap_start) \
start += gap_length; \
if (end > gap_start) \
end += gap_length
#define SCAN_LIST_INITIALIZATION(initialization) \
long depth, min_depth; \
Boolean sexp_flag, ignore_comments, math_exit; \
int c; \
initialization (7); \
depth = (arg_integer (5)); \
min_depth = ((depth >= 0) ? 0 : depth); \
sexp_flag = (BOOLEAN_ARG (6)); \
ignore_comments = (BOOLEAN_ARG (7)); \
math_exit = false
/* Parse Scanning */
#define PEEK_RIGHT(scan) (SYNTAX_TABLE_REF (syntax_table, (*scan)))
#define PEEK_LEFT(scan) (SYNTAX_TABLE_REF (syntax_table, (scan[-1])))
#define MOVE_RIGHT(scan) do \
{ \
if ((++scan) == gap_start) \
scan = gap_end; \
} while (0)
#define MOVE_LEFT(scan) do \
{ \
if ((--scan) == gap_end) \
scan = gap_start; \
} while (0)
#define READ_RIGHT(scan, target) do \
{ \
target = (SYNTAX_TABLE_REF (syntax_table, (*scan++))); \
if (scan == gap_start) \
scan = gap_end; \
} while (0)
#define READ_LEFT(scan, target) do \
{ \
target = (SYNTAX_TABLE_REF (syntax_table, (*--scan))); \
if (scan == gap_end) \
scan = gap_start; \
} while (0)
#define RIGHT_END_P(scan) (scan >= end)
#define LEFT_END_P(scan) (scan <= end)
#define LOSE_IF(expression) do \
{ \
if (expression) \
PRIMITIVE_RETURN (SHARP_F); \
} while (0)
#define LOSE_IF_RIGHT_END(scan) LOSE_IF (RIGHT_END_P (scan))
#define LOSE_IF_LEFT_END(scan) LOSE_IF (LEFT_END_P (scan))
#define SCAN_TO_INDEX(scan) \
((((scan) > gap_start) ? ((scan) - gap_length) : (scan)) - first_char)
#define WIN_IF(expression) do \
{ \
if (expression) \
PRIMITIVE_RETURN (LONG_TO_UNSIGNED_FIXNUM (SCAN_TO_INDEX (start))); \
} while (0)
#define WIN_IF_RIGHT_END(scan) WIN_IF (RIGHT_END_P (scan))
#define WIN_IF_LEFT_END(scan) WIN_IF (LEFT_END_P (scan))
#define RIGHT_QUOTED_P_INTERNAL(scan, quoted) do \
{ \
long sentry; \
\
quoted = false; \
while (true) \
{ \
if (LEFT_END_P (scan)) \
break; \
READ_LEFT (scan, sentry); \
if (! (SYNTAX_ENTRY_QUOTE (sentry))) \
break; \
quoted = (! quoted); \
} \
} while (0)
#define RIGHT_QUOTED_P(scan_init, quoted) do \
{ \
unsigned char * scan = (scan_init); \
RIGHT_QUOTED_P_INTERNAL (scan, quoted); \
} while (0)
#define LEFT_QUOTED_P(scan_init, quoted) do \
{ \
unsigned char * scan = (scan_init); \
MOVE_LEFT (scan); \
RIGHT_QUOTED_P_INTERNAL (scan, quoted); \
} while (0)
/* Quote Parsers */
DEFINE_PRIMITIVE ("QUOTED-CHAR?", Prim_quoted_char_p, 4, 4, 0)
{
NORMAL_INITIALIZATION_BACKWARD (4);
RIGHT_QUOTED_P (start, quoted);
PRIMITIVE_RETURN (BOOLEAN_TO_OBJECT (quoted));
}
/* This is used in conjunction with `scan-list-backward' to find the
beginning of an s-expression. */
DEFINE_PRIMITIVE ("SCAN-BACKWARD-PREFIX-CHARS", Prim_scan_backward_prefix_chars, 4, 4, 0)
{
NORMAL_INITIALIZATION_BACKWARD (4);
while (true)
{
WIN_IF_LEFT_END (start);
LEFT_QUOTED_P (start, quoted);
WIN_IF (quoted);
{
long sentry = (PEEK_LEFT (start));
WIN_IF (! (((SYNTAX_ENTRY_CODE (sentry)) == syntaxcode_quote)
|| (SYNTAX_ENTRY_PREFIX (sentry))));
}
MOVE_LEFT (start);
}
}
DEFINE_PRIMITIVE ("SCAN-FORWARD-PREFIX-CHARS", Prim_scan_forward_prefix_chars, 4, 4, 0)
{
Boolean quoted;
NORMAL_INITIALIZATION_FORWARD (4);
while (true)
{
WIN_IF_RIGHT_END (start);
RIGHT_QUOTED_P (start, quoted);
WIN_IF (quoted);
{
long sentry = (PEEK_RIGHT (start));
WIN_IF (! (((SYNTAX_ENTRY_CODE (sentry)) == syntaxcode_quote)
|| (SYNTAX_ENTRY_PREFIX (sentry))));
}
MOVE_RIGHT (start);
}
}
/* Word Parsers */
DEFINE_PRIMITIVE ("SCAN-FORWARD-TO-WORD", Prim_scan_forward_to_word, 4, 4, 0)
{
NORMAL_INITIALIZATION_FORWARD (4);
while (true)
{
LOSE_IF_RIGHT_END (start);
WIN_IF ((SYNTAX_ENTRY_CODE (PEEK_RIGHT (start))) == syntaxcode_word);
MOVE_RIGHT (start);
}
}
DEFINE_PRIMITIVE ("SCAN-WORD-FORWARD", Prim_scan_word_forward, 4, 4, 0)
{
NORMAL_INITIALIZATION_FORWARD (4);
while (true)
{
LOSE_IF_RIGHT_END (start);
READ_RIGHT (start, sentry);
if ((SYNTAX_ENTRY_CODE (sentry)) == syntaxcode_word)
break;
}
while (true)
{
WIN_IF_RIGHT_END (start);
WIN_IF ((SYNTAX_ENTRY_CODE (PEEK_RIGHT (start))) != syntaxcode_word);
MOVE_RIGHT (start);
}
}
DEFINE_PRIMITIVE ("SCAN-WORD-BACKWARD", Prim_scan_word_backward, 4, 4, 0)
{
NORMAL_INITIALIZATION_BACKWARD (4);
while (true)
{
LOSE_IF_LEFT_END (start);
READ_LEFT (start, sentry);
if ((SYNTAX_ENTRY_CODE (sentry)) == syntaxcode_word)
break;
}
while (true)
{
WIN_IF_LEFT_END (start);
WIN_IF ((SYNTAX_ENTRY_CODE (PEEK_LEFT (start))) != syntaxcode_word);
MOVE_LEFT (start);
}
}
/* S-Expression Parsers */
DEFINE_PRIMITIVE ("SCAN-LIST-FORWARD", Prim_scan_list_forward, 7, 7, 0)
{
SCAN_LIST_INITIALIZATION (NORMAL_INITIALIZATION_FORWARD);
while (true)
{
LOSE_IF_RIGHT_END (start);
c = (*start);
READ_RIGHT(start, sentry);
if ((! (RIGHT_END_P (start))) &&
(SYNTAX_ENTRY_COMSTART_FIRST (sentry)) &&
(SYNTAX_ENTRY_COMSTART_SECOND (PEEK_RIGHT (start))))
{
MOVE_RIGHT (start);
LOSE_IF_RIGHT_END (start);
while (true)
{
READ_RIGHT (start, sentry);
LOSE_IF_RIGHT_END (start);
if ((SYNTAX_ENTRY_COMEND_FIRST (sentry)) &&
(SYNTAX_ENTRY_COMEND_SECOND (PEEK_RIGHT (start))))
{
MOVE_RIGHT (start);
break;
}
}
continue;
}
if (SYNTAX_ENTRY_PREFIX (sentry))
continue;
switch (SYNTAX_ENTRY_CODE (sentry))
{
case syntaxcode_escape:
case syntaxcode_charquote:
LOSE_IF_RIGHT_END (start);
MOVE_RIGHT (start);
case syntaxcode_word:
case syntaxcode_symbol:
if ((depth != 0) || (! sexp_flag))
break;
while (true)
{
WIN_IF_RIGHT_END (start);
switch (SYNTAX_ENTRY_CODE (PEEK_RIGHT (start)))
{
case syntaxcode_escape:
case syntaxcode_charquote:
MOVE_RIGHT (start);
LOSE_IF_RIGHT_END (start);
case syntaxcode_word:
case syntaxcode_symbol:
MOVE_RIGHT (start);
break;
default:
WIN_IF (true);
}
}
case syntaxcode_comment:
if (! ignore_comments)
break;
while (true)
{
LOSE_IF_RIGHT_END (start);
if ((SYNTAX_ENTRY_CODE (PEEK_RIGHT (start))) ==
syntaxcode_endcomment)
break;
MOVE_RIGHT (start);
}
break;
case syntaxcode_math:
if (! sexp_flag)
break;
if ((! (RIGHT_END_P (start))) && (c == *start))
MOVE_RIGHT (start);
if (math_exit)
{
WIN_IF ((--depth) == 0);
LOSE_IF (depth < min_depth);
math_exit = false;
}
else
{
WIN_IF ((++depth) == 0);
math_exit = true;
}
break;
case syntaxcode_open:
WIN_IF ((++depth) == 0);
break;
case syntaxcode_close:
WIN_IF ((--depth) == 0);
LOSE_IF (depth < min_depth);
break;
case syntaxcode_string:
while (true)
{
LOSE_IF_RIGHT_END (start);
if (c == *start)
break;
READ_RIGHT (start, sentry);
if (SYNTAX_ENTRY_QUOTE (sentry))
{
LOSE_IF_RIGHT_END (start);
MOVE_RIGHT (start);
}
}
MOVE_RIGHT (start);
WIN_IF ((depth == 0) && sexp_flag);
break;
default:
break;
}
}
}
DEFINE_PRIMITIVE ("SCAN-LIST-BACKWARD", Prim_scan_list_backward, 7, 7, 0)
{
SCAN_LIST_INITIALIZATION (NORMAL_INITIALIZATION_BACKWARD);
while (true)
{
LOSE_IF_LEFT_END (start);
LEFT_QUOTED_P (start, quoted);
if (quoted)
{
MOVE_LEFT (start);
/* existence of this character is guaranteed by LEFT_QUOTED_P. */
READ_LEFT (start, sentry);
goto word_entry;
}
c = (start[-1]);
READ_LEFT (start, sentry);
if ((! (LEFT_END_P (start))) &&
(SYNTAX_ENTRY_COMEND_SECOND (sentry)) &&
(SYNTAX_ENTRY_COMEND_FIRST (PEEK_LEFT (start))))
{
LEFT_QUOTED_P (start, quoted);
if (! quoted)
{
MOVE_LEFT (start);
LOSE_IF_LEFT_END (start);
while (true)
{
READ_LEFT (start, sentry);
LOSE_IF_LEFT_END (start);
if ((SYNTAX_ENTRY_COMSTART_SECOND (sentry)) &&
(SYNTAX_ENTRY_COMSTART_FIRST (PEEK_LEFT (start))))
{
MOVE_LEFT (start);
break;
}
}
continue;
}
}
switch (SYNTAX_ENTRY_CODE (sentry))
{
case syntaxcode_word:
case syntaxcode_symbol:
word_entry:
if ((depth != 0) || (! sexp_flag))
break;
while (true)
{
WIN_IF_LEFT_END (start);
LEFT_QUOTED_P (start, quoted);
if (quoted)
MOVE_LEFT (start);
else
{
sentry = (PEEK_LEFT (start));
WIN_IF (((SYNTAX_ENTRY_CODE (sentry)) != syntaxcode_word) &&
((SYNTAX_ENTRY_CODE (sentry)) != syntaxcode_symbol));
}
MOVE_LEFT (start);
}
case syntaxcode_math:
if (! sexp_flag)
break;
if ((! (LEFT_END_P (start))) && (c == start[-1]))
MOVE_LEFT (start);
if (math_exit)
{
WIN_IF ((--depth) == 0);
LOSE_IF (depth < min_depth);
math_exit = false;
}
else
{
WIN_IF ((++depth) == 0);
math_exit = true;
}
break;
case syntaxcode_close:
WIN_IF ((++depth) == 0);
break;
case syntaxcode_open:
WIN_IF ((--depth) == 0);
LOSE_IF (depth < min_depth);
break;
case syntaxcode_string:
while (true)
{
LOSE_IF_LEFT_END (start);
LEFT_QUOTED_P (start, quoted);
if ((! quoted) && (c == start[-1]))
break;
MOVE_LEFT (start);
}
MOVE_LEFT (start);
WIN_IF ((depth == 0) && sexp_flag);
break;
case syntaxcode_endcomment:
if (! ignore_comments)
break;
while (true)
{
LOSE_IF_LEFT_END (start);
if ((SYNTAX_ENTRY_CODE (PEEK_LEFT (start))) ==
syntaxcode_comment)
break;
MOVE_LEFT (start);
}
break;
default:
break;
}
}
}
/* Partial S-Expression Parser */
#define LEVEL_ARRAY_LENGTH 100
struct levelstruct { unsigned char * last, * previous; };
#define DONE_IF(expression) do \
{ \
if (expression) \
goto done; \
} while (0)
#define DONE_IF_RIGHT_END(scan) DONE_IF (RIGHT_END_P (scan))
#define SEXP_START() do \
{ \
if (stop_before) goto stop; \
(level -> last) = start; \
} while (0)
DEFINE_PRIMITIVE ("SCAN-SEXPS-FORWARD", Prim_scan_sexps_forward, 7, 7, 0)
{
long target_depth;
Boolean stop_before;
SCHEME_OBJECT state_argument;
long depth;
long in_string; /* -1 or delimiter character */
long in_comment; /* 0, 1, or 2 */
Boolean quoted;
struct levelstruct level_start[LEVEL_ARRAY_LENGTH];
struct levelstruct *level;
struct levelstruct *level_end;
int c;
SCHEME_OBJECT result;
NORMAL_INITIALIZATION_FORWARD (7);
target_depth = (arg_integer (5));
stop_before = (BOOLEAN_ARG (6));
state_argument = (ARG_REF (7));
level = level_start;
level_end = (level_start + LEVEL_ARRAY_LENGTH);
(level -> previous) = NULL;
/* Initialize the state variables from the state argument. */
if (state_argument == SHARP_F)
{
depth = 0;
in_string = -1;
in_comment = 0;
quoted = false;
}
else if ((VECTOR_P (state_argument)) &&
(VECTOR_LENGTH (state_argument)) == 7)
{
SCHEME_OBJECT temp;
temp = (VECTOR_REF (state_argument, 0));
if (FIXNUM_P (temp))
depth = (FIXNUM_TO_LONG (temp));
else
error_bad_range_arg (7);
temp = (VECTOR_REF (state_argument, 1));
if (temp == SHARP_F)
in_string = -1;
else if ((UNSIGNED_FIXNUM_P (temp)) &&
((UNSIGNED_FIXNUM_TO_LONG (temp)) < MAX_ASCII))
in_string = (UNSIGNED_FIXNUM_TO_LONG (temp));
else
error_bad_range_arg (7);
temp = (VECTOR_REF (state_argument, 2));
if (temp == SHARP_F)
in_comment = 0;
else if (temp == (LONG_TO_UNSIGNED_FIXNUM (1)))
in_comment = 1;
else if (temp == (LONG_TO_UNSIGNED_FIXNUM (2)))
in_comment = 2;
else
error_bad_range_arg (7);
quoted = ((VECTOR_REF (state_argument, 3)) != SHARP_F);
if ((in_comment != 0) && ((in_string != -1) || (quoted != false)))
error_bad_range_arg (7);
}
else
error_bad_range_arg (7);
/* Make sure there is enough room for the result before we start. */
Primitive_GC_If_Needed (8);
/* Enter main loop at place appropiate for initial state. */
if (in_comment == 1)
goto start_in_comment;
if (in_comment == 2)
goto start_in_comment2;
if (quoted)
{
quoted = false;
if (in_string != -1)
goto start_quoted_in_string;
else
goto start_quoted;
}
if (in_string != -1)
goto start_in_string;
while (true)
{
DONE_IF_RIGHT_END (start);
c = (*start);
READ_RIGHT (start, sentry);
if ((! (RIGHT_END_P (start))) &&
(SYNTAX_ENTRY_COMSTART_FIRST (sentry)) &&
(SYNTAX_ENTRY_COMSTART_SECOND (PEEK_RIGHT (start))))
{
MOVE_RIGHT (start);
in_comment = 2;
start_in_comment2:
while (true)
{
DONE_IF_RIGHT_END (start);
READ_RIGHT (start, sentry);
if (SYNTAX_ENTRY_COMEND_FIRST (sentry))
{
/* Actually, terminating here is a special case. There
should be a third value of in_comment to handle it. */
DONE_IF_RIGHT_END (start);
if (SYNTAX_ENTRY_COMEND_SECOND (PEEK_RIGHT (start)))
{
MOVE_RIGHT (start);
break;
}
}
}
in_comment = 0;
}
else if (SYNTAX_ENTRY_PREFIX (sentry))
continue;
else
switch (SYNTAX_ENTRY_CODE (sentry))
{
case syntaxcode_escape:
case syntaxcode_charquote:
SEXP_START ();
start_quoted:
if (RIGHT_END_P (start))
{
quoted = true;
DONE_IF (true);
}
MOVE_RIGHT (start);
goto start_atom;
case syntaxcode_word:
case syntaxcode_symbol:
SEXP_START ();
start_atom:
while (! (RIGHT_END_P (start)))
{
switch (SYNTAX_ENTRY_CODE (PEEK_RIGHT (start)))
{
case syntaxcode_escape:
case syntaxcode_charquote:
MOVE_RIGHT (start);
if (RIGHT_END_P (start))
{
quoted = true;
DONE_IF (true);
}
case syntaxcode_word:
case syntaxcode_symbol:
MOVE_RIGHT (start);
break;
default:
goto end_atom;
}
}
end_atom:
(level -> previous) = (level -> last);
break;
case syntaxcode_comment:
in_comment = 1;
start_in_comment:
while (true)
{
DONE_IF_RIGHT_END (start);
READ_RIGHT (start, sentry);
if ((SYNTAX_ENTRY_CODE (sentry)) == syntaxcode_endcomment)
break;
}
in_comment = 0;
break;
case syntaxcode_open:
SEXP_START ();
depth += 1;
level += 1;
if (level == level_end)
error_bad_range_arg (5); /* random error */
(level -> last) = NULL;
(level -> previous) = NULL;
DONE_IF ((--target_depth) == 0);
break;
case syntaxcode_close:
depth -= 1;
if (level != level_start)
level -= 1;
(level -> previous) = (level -> last);
DONE_IF ((++target_depth) == 0);
break;
case syntaxcode_string:
SEXP_START ();
in_string = (c);
start_in_string:
while (true)
{
DONE_IF_RIGHT_END (start);
if (in_string == (*start))
break;
READ_RIGHT (start, sentry);
if (SYNTAX_ENTRY_QUOTE (sentry))
{
start_quoted_in_string:
if (RIGHT_END_P (start))
{
quoted = true;
DONE_IF (true);
}
MOVE_RIGHT (start);
}
}
in_string = -1;
(level -> previous) = (level -> last);
MOVE_RIGHT (start);
break;
}
}
/* NOTREACHED */
stop:
/* Back up to point at character that starts sexp. */
if (start == gap_end)
start = gap_start;
start -= 1;
done:
result = (allocate_marked_vector (TC_VECTOR, 7, true));
FAST_VECTOR_SET (result, 0, (LONG_TO_FIXNUM (depth)));
FAST_VECTOR_SET
(result, 1,
((in_string == -1)
? SHARP_F
: (LONG_TO_UNSIGNED_FIXNUM (in_string))));
FAST_VECTOR_SET
(result, 2,
((in_comment == 0)
? SHARP_F
: (LONG_TO_UNSIGNED_FIXNUM (in_comment))));
FAST_VECTOR_SET (result, 3, (BOOLEAN_TO_OBJECT (quoted)));
FAST_VECTOR_SET
(result, 4,
(((level -> previous) == NULL)
? SHARP_F
: (LONG_TO_UNSIGNED_FIXNUM ((SCAN_TO_INDEX (level -> previous)) - 1))));
FAST_VECTOR_SET
(result, 5,
(((level == level_start) || (((level - 1) -> last) == NULL))
? SHARP_F
: (LONG_TO_UNSIGNED_FIXNUM
((SCAN_TO_INDEX ((level - 1) -> last)) - 1))));
FAST_VECTOR_SET
(result, 6, (LONG_TO_UNSIGNED_FIXNUM (SCAN_TO_INDEX (start))));
PRIMITIVE_RETURN (result);
}